﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Granite.Eventing;
using System.ComponentModel;

namespace Granite.Commons.Tests.Eventing
{
	[TestClass]
	public class PropertyChangedEventManagerTests
	{
		[TestMethod]
		public void PropertyChangedEventManager_Test1()
		{
			var mock = new Mock();
			var manager = new PropertyChangedEventManager(mock);
			try
			{
				manager.AddHandler(null);
				Assert.Fail("Expected an ArgumentNullException");
			}
			catch (ArgumentNullException ex)
			{
				Assert.AreEqual("eventHandler", ex.ParamName, "Parameter name is wrong");
			}
		}

		[TestMethod]
		public void PropertyChangedEventManager_Test2()
		{
			var mock = new Mock();
			var manager = new PropertyChangedEventManager(mock);
			try
			{
				manager.RemoveHandler(null);
				Assert.Fail("Expected an ArgumentNullException");
			}
			catch (ArgumentNullException ex)
			{
				Assert.AreEqual("eventHandler", ex.ParamName, "Parameter name is wrong");
			}
		}

		[TestMethod]
		public void PropertyChangedEventManager_Test3()
		{
			var mock = new Mock();
			var manager = new PropertyChangedEventManager(mock);
			var listener1 = new Listener<PropertyChangedEventArgs>((s, rea) => { });
			var listener2 = new Listener<PropertyChangedEventArgs>((s, rea) => { });
			manager.AddHandler(listener1);
			manager.AddHandler(listener2);
			mock.OnPropertyChanged(new PropertyChangedEventArgs("X"));
			manager.RemoveHandler(listener2);
			manager.RemoveHandler(listener1);
		}

		[TestMethod]
		public void PropertyChangedEventManager_Test4()
		{
			var mock = new Mock();
			var manager = new PropertyChangedEventManager(mock);

			Action add = () =>
			{
				var listener1 = new Listener<PropertyChangedEventArgs>((s, rea) => { });
				manager.AddHandler(listener1);

			};
			add();
			mock.OnPropertyChanged(new PropertyChangedEventArgs("X"));
			TestUtilities.GCCycle();
			mock.OnPropertyChanged(new PropertyChangedEventArgs("X"));

		}


        [TestMethod]
        public void PropertyChangedEventManager_Test5()
        {
            try
            {
                var manager = new PropertyChangedEventManager(null);
                Assert.Fail("Expected an ArgumentNullException");
            }
            catch (ArgumentNullException ex)
            {
                Assert.AreEqual("source", ex.ParamName, "Parameter name is wrong");
            }
        }

		class Mock : INotifyPropertyChanged
		{
			public virtual void OnPropertyChanged(PropertyChangedEventArgs ea)
			{
				if (PropertyChanged != null)
					PropertyChanged(this, ea);
			}
            
			public event PropertyChangedEventHandler PropertyChanged;
		}
	}
}
